package com.atguigu.chap01;


import java.util.concurrent.TimeUnit;

class  Phone{
    //静态同步方法抢类对象锁
    public static synchronized void sendSms(){
        try{
            TimeUnit.SECONDS.sleep(4);
        } catch(InterruptedException e){
            throw new RuntimeException(e);
        }
        System.out.println("短信");
    }
    //普通同步方法抢实例对象锁
    public synchronized void sendMail(){
        System.out.println("邮件");
    }
    //不需要锁就可以执行
    public void hello(){
        System.out.println("hello");
    }
}
/**
 * 八锁问题   任何一个对象都拥有一把锁
 *      class类型对象
 *      普通实例对象
 *
 *
 *
 *看下面这段儿代码，回答多线程的8个问题：
 *
 * 1. 先访问短信，再访问邮件，先打印短信还是邮件
 * A线程有先天优势，先短信后邮件，短信先抢到锁，抢同一个对象的锁，需要排队执行打印任务
 * 2. 停4秒在短信方法内，先打印短信还是邮件
 * 先短信后邮件，A线程有先天优势短信抢到锁后先睡4秒，才会给邮件锁
 * 3. 先访问短信，再访问hello方法，是先打短信还是hello
 * 先hello，后短信，打印短信需要枷锁，A线程虽然抢到锁但要睡觉四秒，而B线程虽然不具有先天优势，后执行但不睡觉，所以先打印
 * 4. 现在有两部手机，第一部发短信，第二部发邮件，先打印短信还是邮件
 *  先打印邮件，后打印短信，两个手机两把锁，各抢各的锁，B线程不用睡觉，A线程要睡觉4秒，所以先打印邮件
 * 5. 两个静态同步方法，1部手机，先打印短信还是邮件
 *  先短信后邮件，两个静态同步方法，去抢Phone.class对象的同一把锁，打印短信先执行，持有锁睡觉，睡醒后打印，释放锁后，打印邮件
 * 6. 两个静态同步方法，2部手机，先打印短信还是邮件
 * 先短信后邮件，两个静态同步方法，去抢Phone.class对象同一把锁，与创建几个实体对象无关，打印短信先执行，持有锁睡觉，睡醒后打印，释放锁后，打印邮件
 * 7. 1个静态同步方法，1个普通同步方法，1部手机，先打印短信还是邮件
 * 先邮件后短信，静态同步方法抢Phone.class对象锁，普通同步方法抢实例对象锁，两个线程两把锁，各抢各的锁，互不影响，邮件不睡觉，先打印邮件，后打印短信
 * 8. 1个静态同步方法，1个普通同步方法，2部手机，先打印短信还是邮件
 * 先邮件后短信，两个线程三把锁，静态同步方法抢Phone.class对象锁，普通同步方法抢实例对象锁，各抢各的锁，互不影响，邮件不睡觉，先打印邮件，后打印短信
 */
public class Lock8 {
    public static void main(String[] args) {
//        Class clazz=Phone.class;
        Phone phone=new Phone(); //普通实例对象 对象头上锁的状态值
        Phone phone2=new Phone();

        new Thread(()->{
            phone.sendSms(); //Phone.sendSms();
        },"A").start();

        new Thread(()->{
//            phone.sendMail(); //Phone.sendMail();
            phone2.sendMail();
        },"B").start();
//        new Thread(()->{
//            phone.hello();
//        },"B").start();
    }
}
